package com.chen.palmar.project.agency;

import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.widget.Toolbar;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.BDLocation;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.chen.palmar.R;
import com.chen.palmar.common.datasource.DataCenter;
import com.chen.palmar.common.override.HttpSubscriber;
import com.chen.palmar.project.agency.adapter.CityListAdapter;
import com.chen.palmar.project.agency.adapter.ResultListAdapter;
import com.primb.androidlibs.utils.ToastUtils;
import com.zaaach.citypicker.CheckPermissionsActivity;
import com.zaaach.citypicker.CheckPermissionsListener;
import com.zaaach.citypicker.model.City;
import com.zaaach.citypicker.model.LocateState;
import com.zaaach.citypicker.utils.StringUtils;
import com.zaaach.citypicker.view.SideLetterBar;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

import butterknife.ButterKnife;
import dmax.dialog.SpotsDialog;
import rx.Subscription;
import rx.subscriptions.CompositeSubscription;

/**
 * Author Bro0cL on 2016/12/16.
 */
public class CityPickerActivity extends CheckPermissionsActivity implements View.OnClickListener, CheckPermissionsListener {
    public static final String KEY_PICKED_CITY = "picked_city";

    private ListView mListView;
    private ListView mResultListView;
    private SideLetterBar mLetterBar;
    private EditText searchBox;
    private ImageView clearBtn;
    private TextView cancelBtn;
    private ViewGroup emptyView;

    private CityListAdapter mCityAdapter;
    private ResultListAdapter mResultAdapter;
    private List<City> mAllCities = new ArrayList<>();
    private List<City> mResultCities = new ArrayList<>();
    public LocationClient mLocationClient = null;
    private CompositeSubscription subscription;
    private SpotsDialog spotsDialog;
    private boolean isLocation = false;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_city_list);

        initData();
        initView();
        initLocation();
        //请求权限
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            mLocationClient.start();
        } else {
            requestPermissions(this, neededPermissions, this);
        }
    }

    private void initLocation() {
        mLocationClient = new LocationClient(this);
        //声明LocationClient类
        mLocationClient.registerLocationListener(new BDAbstractLocationListener() {
            @Override
            public void onReceiveLocation(BDLocation bdLocation) {
                if (bdLocation != null && !isLocation) {
                    String city = bdLocation.getCity();
                    if (!TextUtils.isEmpty(city)) {
                        isLocation = true;
                        String district = bdLocation.getDistrict();
                        String location = StringUtils.extractLocation(city, district);
                        mCityAdapter.updateLocateState(LocateState.SUCCESS, city);
                    }
                } else if (bdLocation == null){
                    //定位失败
                    mCityAdapter.updateLocateState(LocateState.FAILED, null);
                }
            }
        });
        LocationClientOption option = new LocationClientOption();

        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
        //可选，设置定位模式，默认高精度
        //LocationMode.Hight_Accuracy：高精度；
        //LocationMode. Battery_Saving：低功耗；
        //LocationMode. Device_Sensors：仅使用设备；

        option.setCoorType("bd09ll");
        //可选，设置返回经纬度坐标类型，默认gcj02
        //gcj02：国测局坐标；
        //bd09ll：百度经纬度坐标；
        //bd09：百度墨卡托坐标；
        //海外地区定位，无需设置坐标类型，统一返回wgs84类型坐标

        option.setScanSpan(0);
        //可选，设置发起定位请求的间隔，int类型，单位ms
        //如果设置为0，则代表单次定位，即仅定位一次，默认为0
        //如果设置非0，需设置1000ms以上才有效

        option.setOpenGps(true);
        //可选，设置是否使用gps，默认false
        //使用高精度和仅用设备两种定位模式的，参数必须设置为true

        option.setLocationNotify(true);
        //可选，设置是否当GPS有效时按照1S/1次频率输出GPS结果，默认false

        option.setIgnoreKillProcess(false);
        //可选，定位SDK内部是一个service，并放到了独立进程。
        //设置是否在stop的时候杀死这个进程，默认（建议）不杀死，即setIgnoreKillProcess(true)

        option.SetIgnoreCacheException(false);
        //可选，设置是否收集Crash信息，默认收集，即参数为false

        option.setWifiCacheTimeOut(5 * 60 * 1000);
        //可选，7.2版本新增能力
        //如果设置了该接口，首次启动定位时，会先判断当前WiFi是否超出有效期，若超出有效期，会先重新扫描WiFi，然后定位

        option.setEnableSimulateGps(false);
        //可选，设置是否需要过滤GPS仿真结果，默认需要，即参数为false

        option.setIsNeedLocationDescribe(true);
        option.setIsNeedAddress(true);

        mLocationClient.setLocOption(option);
        //mLocationClient为第二步初始化过的LocationClient对象
        //需将配置好的LocationClientOption对象，通过setLocOption方法传递给LocationClient对象使用
        //更多LocationClientOption的配置，请参照类参考中LocationClientOption类的详细说明
    }

    private void initData() {
        subscription = new CompositeSubscription();
        getAllCities();

        mCityAdapter = new CityListAdapter(this, mAllCities);
        mCityAdapter.setOnCityClickListener(new CityListAdapter.OnCityClickListener() {
            @Override
            public void onCityClick(String name) {
                backWithData(name);
            }

            @Override
            public void onLocateClick() {
                mCityAdapter.updateLocateState(LocateState.LOCATING, null);
                requestPermissions(CityPickerActivity.this, neededPermissions, CityPickerActivity.this);
            }
        });

        mResultAdapter = new ResultListAdapter(this, null);
    }

    private void getAllCities() {
        HashMap<String, Object> map = new HashMap<>();
        Subscription subscribe = DataCenter.listCityInfo(map).subscribe(new HttpSubscriber<List<City>>(this, showLoading("加载中")) {
            @Override
            public void onNext(List<City> cities) {
                mAllCities.addAll(cities);
                mCityAdapter.notifyDataSetChanged();
            }
        });
        subscription.add(subscribe);
    }

    private void initView() {
        mListView = (ListView) findViewById(R.id.listview_all_city);
        mListView.setAdapter(mCityAdapter);
        TextView title = (TextView) findViewById(R.id.title_bar);
        title.setText("城市选择");
        Toolbar toolBar = (Toolbar) findViewById(R.id.tool_bar);
        toolBar.setNavigationOnClickListener(v -> CityPickerActivity.this.finish());
        TextView overlay = (TextView) findViewById(R.id.tv_letter_overlay);
        mLetterBar = (SideLetterBar) findViewById(R.id.side_letter_bar);
        mLetterBar.setOverlay(overlay);
        mLetterBar.setOnLetterChangedListener(new SideLetterBar.OnLetterChangedListener() {
            @Override
            public void onLetterChanged(String letter) {
                int position = mCityAdapter.getLetterPosition(letter);
                mListView.setSelection(position);
            }
        });

        searchBox = (EditText) findViewById(com.zaaach.citypicker.R.id.et_search);
        searchBox.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
            }

            @Override
            public void afterTextChanged(Editable s) {
                String keyword = s.toString();
                if (TextUtils.isEmpty(keyword)) {
                    clearBtn.setVisibility(View.GONE);
                    emptyView.setVisibility(View.GONE);
                    mResultListView.setVisibility(View.GONE);
                } else {
                    clearBtn.setVisibility(View.VISIBLE);
                    mResultListView.setVisibility(View.VISIBLE);
                    mResultCities = searchCity(keyword);
                    if (mResultCities == null || mResultCities.size() == 0) {
                        emptyView.setVisibility(View.VISIBLE);
                    } else {
                        emptyView.setVisibility(View.GONE);
                        mResultAdapter.changeData(mResultCities);
                    }
                }
            }
        });

        emptyView = (ViewGroup) findViewById(com.zaaach.citypicker.R.id.empty_view);
        mResultListView = (ListView) findViewById(R.id.listview_search_result);
        mResultListView.setAdapter(mResultAdapter);
        mResultListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                backWithData(mResultAdapter.getItem(position).getName());
            }
        });

        clearBtn = (ImageView) findViewById(com.zaaach.citypicker.R.id.iv_search_clear);
        cancelBtn = (TextView) findViewById(com.zaaach.citypicker.R.id.tv_search_cancel);

        clearBtn.setOnClickListener(this);
        cancelBtn.setOnClickListener(this);
    }

    private List<City> searchCity(String keyword) {
        ArrayList<City> cities = new ArrayList<>();
        for (int i = 0; i < mAllCities.size(); i++) {
            if (mAllCities.get(i).getName().contains(keyword) || mAllCities.get(i).getPinyin().contains(keyword)) {
                cities.add(mAllCities.get(i));
            }
        }
        Collections.sort(cities, new DataCenter.CityComparator());
        return cities;
    }

    private void backWithData(String city) {
        Intent data = new Intent();
        boolean isOk = false;
        for (int i = 0; i < mAllCities.size(); i++) {
            City cityEntity = mAllCities.get(i);
            if (cityEntity.getName().equals(city)) {
                data.putExtra(KEY_PICKED_CITY, cityEntity);
                isOk = true;
                break;
            }
        }
        if (isOk) {
            setResult(RESULT_OK, data);
            finish();
        } else {
            ToastUtils.showShort("未找到对应城市id");
        }
    }

    @Override
    public void onClick(View v) {
        int i = v.getId();
        if (i == com.zaaach.citypicker.R.id.iv_search_clear) {
            searchBox.setText("");
            clearBtn.setVisibility(View.GONE);
            emptyView.setVisibility(View.GONE);
            mResultListView.setVisibility(View.GONE);
            mResultCities = null;
        } else if (i == com.zaaach.citypicker.R.id.tv_search_cancel) {
            finish();
        }
    }

    @Override
    public void onGranted() {
        mLocationClient.start();
    }

    @Override
    public void onDenied(List<String> permissions) {
        Toast.makeText(this, "权限被禁用，请到设置里打开", Toast.LENGTH_SHORT).show();
        mCityAdapter.updateLocateState(LocateState.FAILED, null);
    }

    public SpotsDialog showLoading(String text) {
        if (null == spotsDialog) {
            spotsDialog = new SpotsDialog(this, text);
        }
        spotsDialog.show();
        return spotsDialog;
    }

    public void hideLoading() {
        if (null != spotsDialog) {
            spotsDialog.dismiss();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        ButterKnife.unbind(this);
        if (null != subscription) {
            subscription.clear();
            subscription.unsubscribe();
        }
        if (spotsDialog != null && spotsDialog.isShowing()) {
            hideLoading();
        }
        mLocationClient.stop();
    }

}
